home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 16 code / CollaboDraw / commands.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-24  |  10.8 KB  |  482 lines  |  [TEXT/MPS ]

  1. /*-------------------------------------------------------------------------------------
  2.  *
  3.  * Simple Sample PowerTalk Application Framework
  4.  *
  5.  * ©1991-1993 Apple Computer
  6.  *
  7.  -------------------------------------------------------------------------------------*/
  8. /*
  9.  * commands.c -- called in response to menu commands or appleevents
  10.  *
  11.  * change history:
  12.  *
  13.  * SJF        08/23/93        1.0f1        update to final headers, fix comments
  14.  * SJF        04/21/93        1.0b2        update to b2
  15.  * SJF        03/01/93        1.0b1        added digital signatures
  16.  * SJF        02/09/93        1.0b1        update to b1
  17.  * SJF        10/13/92        1.0d4        update to a11
  18.  * SJF        09/09/92        1.0d3        update to a9
  19.  * SJF        05/07/92        1.0d2        update to a6
  20.  * SJF        11/06/91        1.0d1        initial coding
  21.  *
  22.  */
  23.  
  24. #ifndef __TYPES__
  25. #include <Types.h>
  26. #endif
  27.  
  28. #ifndef __DIALOGS__
  29. #include <Dialogs.h>
  30. #endif
  31.  
  32. #ifndef __CONTROLS__
  33. #include <Controls.h>
  34. #endif
  35.  
  36. #ifndef __MENUS__
  37. #include <Menus.h>
  38. #endif
  39.  
  40. #ifndef __STANDARDFILE__
  41. #include <StandardFile.h>
  42. #endif
  43.  
  44. #ifndef __FILES__
  45. #include <Files.h>
  46. #endif
  47.  
  48. #ifndef __SCRIPT__
  49. #include <Script.h>
  50. #endif
  51.  
  52. #ifndef __OCEMAIL__
  53. #include <OCEMail.h>
  54. #endif
  55.  
  56. #ifndef __OCESTANDARDMAIL__
  57. #include <OCEStandardMail.h>
  58. #endif
  59.  
  60. #include "const.h"
  61. #include "strconst.h"
  62. #include "mymenus.h"
  63. #include "mytypes.h"
  64. #include "globals.h"
  65. #include "utils.h"
  66. #include "windowstuff.h"
  67. #include "mystandardmail.h"
  68.  
  69. #include "commands.h"
  70.  
  71. /* closes a window in response to the File:Close menu item */
  72.  
  73. void CommCloseWindow(WindowPtr window)
  74. {
  75.     WInfoHndl infoHndl;
  76.     Boolean shouldClose;
  77.     
  78.     if (!IsAppWindow(window))
  79.         return;
  80.         
  81.     infoHndl = GetWindowInfo(window);
  82.     
  83.     if (!CanCloseLetter(window))    // see if we're allowed to close the letter
  84.         shouldClose = false;
  85.     else {
  86.         if ((**infoHndl).changed)
  87.             shouldClose = WarnOnWindowClose(window);    // see if user really wants to close letter
  88.         else
  89.             shouldClose = true;
  90.     }
  91.     
  92.     if (shouldClose) {
  93.         SendWindowMessage(window,kDeactivateMessage,nil);    // send window a deactivate message
  94.         SendWindowMessage(window,kDestroyMessage,nil);        // sent window a destroy message
  95.         
  96.         DisposHandleChk(infoHndl);    
  97.         DisposeWindow(window);
  98.     }
  99.     else gDone = false;    // we might be quitting, so we'd want to abort that
  100. }
  101.  
  102.  
  103. /* processes edit menu commands */
  104.  
  105. void CommEdit(WindowPtr window,short command)
  106. {
  107.     short msg;
  108.     
  109.     if (!IsAppWindow(window))
  110.         return;
  111.  
  112.     switch (command) {
  113.         case kUndoItem:
  114.             msg = kUndoMessage;
  115.             break;
  116.         case kCutItem:
  117.             msg = kCutMessage;
  118.             break;
  119.         case kCopyItem:
  120.             msg = kCopyMessage;
  121.             break;
  122.         case kPasteItem:
  123.             msg = kPasteMessage;
  124.             break;
  125.         case kClearItem:
  126.             msg = kClearMessage;
  127.             break;
  128.         case kSelectAllItem:
  129.             msg = kSelectAllMessage;
  130.             break;
  131.         default:
  132.             return;
  133.     }
  134.     SendWindowMessage(window,msg,nil);    // send the edit message to the window
  135. }
  136.  
  137.  
  138. /* called in response to the user selecting the "Preferences..." menu item */
  139. /* displays the preferences modal dialog and saves the changes in the */
  140. /* gPreferences global */
  141.  
  142. void CommEditPreferences(void)
  143. {
  144.     DialogPtr theDialog;
  145.     short iType;
  146.     Handle iHndl;
  147.     Rect iRect;
  148.     short item;
  149.     Boolean *prefSwitchPtr;
  150.     MyPreferences newPreferences;
  151.     
  152.     BlockMove(&gPreferences,&newPreferences,sizeof(MyPreferences));
  153.     
  154.     theDialog = GetNewDialog(kPrefsDialogID,nil,(WindowPtr)-1L);
  155.     MyDrawDefaultButtonOutline(theDialog,ok);
  156.     
  157.     // set up our dialog with the initial values
  158.     
  159.     GetDItem(theDialog,kCloseAfterSave,&iType,&iHndl,&iRect);
  160.     SetCtlValue((ControlHandle)iHndl,newPreferences.closeOnSend);
  161.     GetDItem(theDialog,kShowCloseOptions,&iType,&iHndl,&iRect);
  162.     SetCtlValue((ControlHandle)iHndl,newPreferences.closeOptionsDialog);
  163.     GetDItem(theDialog,kExpandMailerCreate,&iType,&iHndl,&iRect);
  164.     SetCtlValue((ControlHandle)iHndl,newPreferences.expandOnCreate);
  165.     GetDItem(theDialog,kExpandMailerOpen,&iType,&iHndl,&iRect);
  166.     SetCtlValue((ControlHandle)iHndl,newPreferences.expandOnOpen);
  167.     
  168.     // let the user play with the dialog
  169.     
  170.     do {
  171.         ModalDialog(nil,&item);
  172.         if (item>=kCloseAfterSave && item<=kExpandMailerOpen) {
  173.             switch (item) {
  174.                 case kCloseAfterSave:
  175.                     prefSwitchPtr = &newPreferences.closeOnSend;
  176.                     break;
  177.                 case kShowCloseOptions:
  178.                     prefSwitchPtr = &newPreferences.closeOptionsDialog;
  179.                     break;
  180.                 case kExpandMailerCreate:
  181.                     prefSwitchPtr = &newPreferences.expandOnCreate;
  182.                     break;
  183.                 case kExpandMailerOpen:
  184.                     prefSwitchPtr = &newPreferences.expandOnOpen;
  185.                     break;
  186.             }
  187.             *prefSwitchPtr = !(*prefSwitchPtr);
  188.             GetDItem(theDialog,item,&iType,&iHndl,&iRect);
  189.             SetCtlValue((ControlHandle)iHndl,*prefSwitchPtr);
  190.         }
  191.         
  192.     } while (item!=ok && item!=cancel);
  193.     
  194.     // store the new preferences in the gPreferences global
  195.     
  196.     if (item==ok)
  197.         BlockMove(&newPreferences,&gPreferences,sizeof(MyPreferences));
  198.     
  199.     DisposeDialog(theDialog);
  200. }
  201.  
  202.  
  203. /* processes print menu item */
  204.  
  205. void CommPrint(WindowPtr window)
  206. {
  207.     if (IsAppWindow(window))
  208.         SendWindowMessage(window,kPrintMessage,nil);
  209. }
  210.  
  211.  
  212. /* processes page setup menu item */
  213.  
  214. void CommPageSetup(WindowPtr window)
  215. {
  216.     WInfoPtr infoPtr;
  217.     char hState;
  218.     Boolean changed;
  219.     
  220.     SetCursor(&qd.arrow);
  221.  
  222.     if (!IsAppWindow(window))
  223.         return;
  224.     
  225.     infoPtr = BeginWindowAccess(window,&hState);
  226.     
  227.     PrOpen();
  228.     changed = PrStlDialog(infoPtr->printRecord);    // display page setup dialog
  229.     if (PrError()!=noErr)
  230.         DoError(PrError());
  231.     PrClose();
  232.     
  233.     if (changed)
  234.         SendWindowMessage(window,kPageSetupMessage,nil);    // tell window that we changed things
  235.  
  236.     EndWindowAccess(window,hState);
  237. }
  238.  
  239.  
  240. /* show about box */
  241.  
  242. void CommAbout(void)
  243. {
  244.     DialogPtr theDlg;
  245.     short item;
  246.         
  247.     theDlg = GetNewDialog(kAboutBoxID,nil,(WindowPtr)-1L);
  248.     ModalDialog(nil,&item);
  249.     DisposeDialog(theDlg);
  250. }
  251.  
  252.  
  253. /* new command- make a new drawing window */
  254.  
  255. void CommNew(void)
  256. {
  257.     MakeWindow(kDrawWindow,nil,nil,true);
  258. }
  259.  
  260.  
  261. /* open command- open a drawing or a letter */
  262.  
  263. void CommOpen(void)
  264. {
  265.     StandardFileReply sfReply;
  266.     SFTypeList typeList;
  267.     OSErr err;
  268.     WindowPtr window;
  269.     
  270.     typeList[0] = kDrawingType;
  271.     typeList[1] = kCDLtrMsgType;
  272.     
  273.     StandardGetFile(nil,2,typeList,&sfReply);
  274.     if (sfReply.sfGood) {
  275.         err = LoOpen(true, &sfReply.sfFile, nil,true,&window);    // call through to low-level call
  276.         if (err!=noErr)
  277.             DoError(err);
  278.     }
  279. }
  280.  
  281.  
  282. /* low-level open (can be called by aevt or CommOpen above) */
  283. /* opens either a letter (from disk or in tray) or a drawing */
  284.  
  285. OSErr LoOpen(Boolean diskForm, FSSpec *fSpec, LetterSpec *lSpec,Boolean showWindow,
  286.             WindowPtr *openedWindow)
  287. {
  288.     WindowPtr window;
  289.     WInfoHndl info;
  290.     short wType;
  291.     OSErr err;
  292.     FInfo fInfo;
  293.     LetterDescriptor letterDesc;
  294.     void *message;
  295.     RString name;
  296.     
  297.     name.charSet = smRoman;
  298.     name.dataLength = 0;
  299.     
  300.     *openedWindow = nil;
  301.  
  302.     // if file is on disk, put an fsspec in the load message
  303.     
  304.     if (diskForm) {
  305.         err = FSpGetFInfo(fSpec,&fInfo);
  306.         if (err!=noErr)
  307.             return err;
  308.         
  309.         switch (fInfo.fdType) {
  310.             case kDrawingType:
  311.                 wType = kDrawWindow;
  312.                 message = fSpec;
  313.                 break;
  314.             case kCDLtrMsgType:
  315.                 wType = kDrawMailerWindow;
  316.                 letterDesc.onDisk = true;
  317.                 BlockMove(fSpec,&letterDesc.u.fileSpec,sizeof(FSSpec));
  318.                 message = &letterDesc;
  319.                 break;
  320.             default:
  321.                 return kInternalError;
  322.         }
  323.     }
  324.     else {
  325.         wType = kDrawMailerWindow;    // put a letter spec into the message for in tray letters
  326.         letterDesc.onDisk = false;
  327.         BlockMove(lSpec,&letterDesc.u.mailboxSpec,sizeof(LetterSpec));
  328.         message = &letterDesc;
  329.     }
  330.         
  331.     window = MakeWindow(wType,nil,nil,false);    // create the window
  332.  
  333.     if (window) {
  334.         info = GetWindowInfo(window);
  335.         SendWindowMessage(window,kLoadMessage,message);    // load the window data (letter or drawing)
  336.         if (diskForm)
  337.             BlockMove(fSpec->name, name.body - 1, fSpec->name[0] + 1);
  338.         else {
  339.             (**info).saved = false;
  340.             err = SMPGetComponentInfo(window, 1, kSMPRegarding, &name);    // set the filename to
  341.             BlockMove(name.body - 1,fSpec->name,name.dataLength+1);        // the letter's subject
  342.             if (err!=noErr)
  343.                 return err;
  344.         }
  345.         SetWTitle(window, name.body - 1);
  346.         BlockMove(fSpec,&(*info)->fileSpec,sizeof(FSSpec));    // copy the fsspec into the window info
  347.         if (showWindow)
  348.             ShowWindow(window);
  349.     }
  350.     *openedWindow = window;
  351.     return noErr;
  352. }
  353.  
  354.  
  355. /* save command- returns false if user cancelled save */
  356.  
  357. Boolean CommSaveFile(WindowPtr window)
  358. {
  359.     WInfoHndl info;
  360.     
  361.     if (!IsAppWindow(window))
  362.         return true;
  363.     
  364.     info = GetWindowInfo(window);
  365.     if (!(**info).changed)                // don't do anything if we haven't changed the document
  366.         return true;
  367.         
  368.     if (!(**info).saved)
  369.         return CommSaveAsFile(window);    // if we haven't saved before, do a save as
  370.     else {
  371.         LoSaveFile(window,kSMPSave);    // call the low-level save
  372.         return true;
  373.     }
  374. }
  375.  
  376.  
  377. /* save as command (display standard file to get filename and then call LoSaveFile) */
  378.  
  379. Boolean CommSaveAsFile(WindowPtr window)
  380. {
  381.     WInfoHndl info;
  382.     StandardFileReply sfReply;
  383.     Str255 promptString;
  384.     Str255 defaultFilename;
  385.     StringPtr fileName;
  386.     WindowKind kind;
  387.     
  388.     info = GetWindowInfo(window);
  389.  
  390.     // get the default filename
  391.     
  392.     fileName = (**info).fileSpec.name;
  393.     if (fileName[0]==0) {
  394.         GetResString(defaultFilename,kDefaultFilenameID,kDefaultFilename);
  395.         fileName = defaultFilename;
  396.     }
  397.         
  398.     if (!IsAppWindow(window))
  399.         return true;
  400.     
  401.     // get the document type string for "save letter/drawing as:"
  402.     
  403.     kind = GetWindowKind(window);
  404.     switch (kind) {
  405.         case kDrawWindow:
  406.             GetResString(promptString,kPromptStringID,kPromptString);
  407.             break;
  408.         case kDrawMailerWindow:
  409.             GetResString(promptString,kSaveLetterAsID,kSaveLetterAs);
  410.             break;
  411.     }
  412.  
  413.     StandardPutFile(promptString,fileName,&sfReply);
  414.     if (sfReply.sfGood) {
  415.         BlockMove(&sfReply.sfFile,&((**info).fileSpec),sizeof(FSSpec));
  416.         LoSaveFile(window,kSMPSaveAs);
  417.         return true;
  418.     }
  419.     else
  420.         return false;
  421. }
  422.  
  423.  
  424. /* low-level save file */
  425.  
  426. void LoSaveFile(WindowPtr window,SMPSaveType how)
  427. {
  428.     SendWindowMessage(window,kSaveMessage,(void *)how);    // just send the window the save message
  429. }
  430.  
  431.  
  432. /* warn the user that we're going to close the window via a "Do you want to save changes" dialog */
  433.  
  434. Boolean WarnOnWindowClose(WindowPtr window)
  435. {
  436.     short item;
  437.     WInfoPtr infoPtr;
  438.     char hState;
  439.     Boolean returnValue;
  440.     WindowKind kind;
  441.     Str63 documentKind,quitReason;
  442.     
  443.     // get document type for "Are you sure you want to close the drawing/letter xxx"
  444.     
  445.     kind = GetWindowKind(window);
  446.     switch (kind) {
  447.         case kDrawWindow:
  448.             GetResString(documentKind,kDrawingID,kDrawing);
  449.             break;
  450.         case kDrawMailerWindow:
  451.             GetResString(documentKind,kLetterID,kLetter);
  452.             break;
  453.     }
  454.     
  455.     // get either the "before quitting" or "before closing" string, depending on which we're doing
  456.     
  457.     if (gDone)
  458.         GetResString(quitReason,kQuittingID,kQuitting);
  459.     else
  460.         GetResString(quitReason,kClosingID,kClosing);
  461.         
  462.     infoPtr = BeginWindowAccess(window,&hState);
  463.     ParamText(documentKind,infoPtr->fileSpec.name,quitReason,nil);
  464.     EndWindowAccess(window,hState);
  465.     
  466.     SetCursor(&qd.arrow);
  467.     item = StopAlert(kWarnCloseID,nil);
  468.     
  469.     switch (item) {
  470.         case cancel:
  471.             returnValue = false;    // if they cancel, return false to cancel the close
  472.             break;
  473.         case kDontSave:
  474.             returnValue = true;        // if they click don't save, return true to continue
  475.             break;
  476.         case ok:
  477.             returnValue = CommSaveFile(window);    // if they click yes, return true if the save works
  478.             break;
  479.     }
  480.     return returnValue;
  481. }
  482.